package com.jh.paymentchannel.pojo;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.base.MoreObjects;
import com.google.common.collect.BoundType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Range;
import org.inferred.freebuilder.FreeBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.data.util.Pair;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;


/**
 * 分润费率。
 *
 * @author Fuchun
 * @since 1.0
 */
@FreeBuilder
@JsonDeserialize(builder = ShareProfitRate.Builder.class)
public abstract class ShareProfitRate {

    // 默认的分润费率
    private static final BigDecimal DEFAULT_PROFIT_RATE = new BigDecimal("0.006");

    /**
     * 默认的分润费率。
     */
    public abstract BigDecimal getDefaultRate();

    /**
     * 分段消息（还款）额的分润费率。
     */
    public abstract List<ProfitRatePart> getRateParts();

    @JsonIgnore
    public boolean isEmptyRateParts() {
        return getRateParts() == null ||
                getRateParts().isEmpty();
    }

    /**
     * 获取给定消费（还款）额所在范围的分润费率，如果不在范围内，则返回默认费率。
     *
     * @param amount 消费（还款）额。
     * @return 返回给定消费（还款）额所在范围的分润费率。
     */
    public BigDecimal getRate(@Nullable BigDecimal amount) {
        if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0 ||
                isEmptyRateParts()) {
            return getDefaultRate();
        }
        for (ProfitRatePart ratePart : getRateParts()) {
            if (ratePart.contains(amount)) {
                return ratePart.rate;
            }
        }
        return getDefaultRate();
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("defaultRate", getDefaultRate())
                .add("rateParts", getRateParts())
                .toString();
    }

    /**
     * {@link ShareProfitRate} instance builder.
     */
    public static class Builder extends ShareProfitRate_Builder {

        public Builder() {
            setDefaultRate(DEFAULT_PROFIT_RATE);
        }
    }

    /**
     * 分润费率分段配置结构。
     */
    public static class ProfitRatePart implements Serializable {

        private static final long serialVersionUID = 1L;

        /** 消费额符合的范围。*/
        private final Range<BigDecimal> range;
        /** 分润比率 */
        private final BigDecimal rate;

        @JsonCreator
        public ProfitRatePart(
                @JsonProperty("range") Range<BigDecimal> range,
                @JsonProperty("rate") BigDecimal rate) {
            this.range = range;
            this.rate = rate;
        }

        @JsonProperty("range")
        public Range<BigDecimal> getRange() {
            return range;
        }

        @JsonProperty("rate")
        public BigDecimal getRate() {
            return rate;
        }

        public boolean contains(BigDecimal amount) {
            if (amount == null) return false;
            return range != null && range.contains(amount);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof ProfitRatePart)) return false;
            ProfitRatePart that = (ProfitRatePart) o;
            return Objects.equals(range, that.range) &&
                    Objects.equals(rate, that.rate);
        }

        @Override
        public int hashCode() {
            return Objects.hash(range, rate);
        }

        @Override
        public String toString() {
            return MoreObjects.toStringHelper(this)
                    .add("range", range)
                    .add("rate", rate)
                    .toString();
        }
    }
}
